package com.zelix.analy;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 头一次碰上带bsmArgs的invokedynamic的指令,大部分都是空数组
 */
public class InvokedynamicArgs {
    public static void main(String[] args) throws IOException {

        JarFile jarFile = null;
        try {
            jarFile = new JarFile("./file/lsrv-floating.jar");
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (jarFile == null) {
            return;
        }

        String rule = "com/jetbrains/ls/floating/upstream/b.class";

        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            if (entry.getName().endsWith(".class") && entry.getName().startsWith(rule)) {//只分析class文件
                System.out.println(entry.getName());

                ClassReader cr = new ClassReader(jarFile.getInputStream(entry));
                ClassNode cn = new ClassNode();
                cr.accept(cn, 0);

                List<MethodNode> methods = cn.methods;


                for (MethodNode methodNode : methods) {
                    if ("a".equals(methodNode.name) && "(J)V".equals(methodNode.desc)) {
                        InsnList insnList = methodNode.instructions;
                        for (AbstractInsnNode insnNode : insnList) {
                            if (insnNode instanceof InvokeDynamicInsnNode) {
                                InvokeDynamicInsnNode dynamicNode = (InvokeDynamicInsnNode) insnNode;
                                System.out.println(dynamicNode.name);
                                System.out.println(dynamicNode.desc);
                                System.out.println(Arrays.asList(dynamicNode.bsmArgs));
                                System.out.println(dynamicNode.bsm);
                                System.out.println(dynamicNode.bsm.getOwner());
                                System.out.println(dynamicNode.bsm.getName());
                                System.out.println(dynamicNode.bsm.getDesc());
                                System.out.println(dynamicNode.bsm.getTag());
                            }
                        }
                    }
                }
            }
        }
    }
}
